package com.shangxian.giveithome.service.impl;

import cn.hutool.core.util.StrUtil;
import com.shangxian.giveithome.code.CommonCode;
import com.shangxian.giveithome.code.ImgFeiCode;
import com.shangxian.giveithome.entity.UserDetails;
import com.shangxian.giveithome.entity.community.IssueImg;
import com.shangxian.giveithome.exception.ExceptionUtils;
import com.shangxian.giveithome.exception.ImgException;
import com.shangxian.giveithome.mapper.IssueImgMapper;
import com.shangxian.giveithome.result.Result;
import com.shangxian.giveithome.service.IssueImgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

import static com.shangxian.giveithome.properties.ImageProperties.IMG_SIZE;

@Slf4j
@Service
public class IssueImgServiceImpl implements IssueImgService {

    @Resource
    private IssueImgMapper issueImgMapper;

    @Override
    public List<IssueImg> queryByIds(List<Long> imgIds) {
        return null;
    }

    /**
     * 删除文件
     * @param header
     * @param issueImgs
     * @return
     */
    @Override
    public Result delete(UserDetails header, List<IssueImg> issueImgs) {
        if (CollectionUtils.isEmpty(issueImgs)){
            //该数据为空
            return Result.error(ImgFeiCode.FILE_NOT_NULL);
        }
        for (IssueImg issueImg1 : issueImgs){
            if (! issueImg1.getUserId().equals(header.getId())){
                //用户不匹配
                return Result.error(ImgFeiCode.USER_NOT_PRE);
            }
        }
        issueImgMapper.deleteById(issueImgs);
        deletes(issueImgs);
        return Result.success(CommonCode.DELETE_SUCCESS);
    }

    /**
     * 新增图片
     * @param header
     * @param id
     * @param multipartFile
     * @return
     */
    @Override
    @Transactional
    public IssueImg inset(UserDetails header, Long id, MultipartFile multipartFile) {
        System.out.println(multipartFile.getOriginalFilename());
        if (!checkFileSize(multipartFile.getSize(), IMG_SIZE,"M")){
            ExceptionUtils.error(ImgFeiCode.FILE_SIZE);
        }
        String src_file_name = multipartFile.getOriginalFilename();
        String[] strArray = src_file_name.split("\\.");
        String ext_Name = strArray[strArray.length -1];
        String file_Name = strArray[0];
        byte[] bytes = null;
        try{
            bytes = multipartFile.getBytes();
            System.out.println(ext_Name);
        }catch (IOException e){
            log.error("【获取文件异常】");
            System.out.println("1.成功执行？");
            ExceptionUtils.error(ImgFeiCode.UPLOAD_ERROR);
        }
        String filePath = uploadFile(bytes,ext_Name,file_Name);
        if (StringUtils.isEmpty(filePath)){
            log.error("【上传异常】");
            System.out.println("2.成功执行？");
            ExceptionUtils.error(ImgFeiCode.UPLOAD_ERROR);
        }

        IssueImg issueImg = new IssueImg();
        issueImg.setPath(filePath);
        issueImg.setUserId(header.getId());
        if (id != null){
            issueImg.setKeyId(id);
            issueImgMapper.saveById(issueImg);
        }else {
            issueImgMapper.save(issueImg);
        }
        Long aLong = issueImgMapper.queryByIds(issueImg.getId());
        issueImg.setKeyId(aLong);
        return issueImg;


    }

    /**
     * 根据id查询图片集合
     * @param imgId
     * @return
     */
    @Override
    public List<IssueImg> queryByImages(Long imgId) {
//        return issueImgMapper.
        return null;
    }




    /**
     * 删除封装
     *
     * @param issueImgs
     * @return
     */
    public Result deletes(List<IssueImg> issueImgs) {
        for (IssueImg issueImg1 : issueImgs) {
            Boolean aBoolean = deleteFile(issueImg1.getPath());
            if (!aBoolean) {
                //删除失败
                Result result = new Result(ImgFeiCode.DELETE_ERROR);
                throw new ImgException(result);
            }
        }
        return Result.error(CommonCode.DELETE_SUCCESS);
    }



    /**
     * 上传文件
     *
     * @param bytes
     * @param ext_Name
     * @param file_Name
     * @return
     */
    private String uploadFile(byte[] bytes, String ext_Name, String file_Name) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            System.out.println("00000000000");
            System.out.println("成功执行？");
            ClientGlobal.initByProperties("fastdfs.properties");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            NameValuePair[] pairs = new NameValuePair[1];
            pairs[0] = new NameValuePair(file_Name, ext_Name);
            System.out.println("成功执行？");
            System.out.println("获取的对象为："+storageClient);
            String[] strings = storageClient.upload_file(bytes, ext_Name, null);
            System.out.println("执行到了这里？"+strings);
            stringBuilder.append(StrUtil.join("/", (Object) strings));
            System.out.println(strings);
        } catch (IOException | MyException e) {
            ExceptionUtils.error(ImgFeiCode.UPLOAD_ERROR);
        }
        return stringBuilder.toString();
    }




    /**
     * 删除文件
     *
     * @param filePath
     * @return
     */
    private Boolean deleteFile(String filePath) {
        try {
            // 链接FastDFS服务器，创建tracker和Stroage
            ClientGlobal.initByProperties("fastdfs.properties");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            int i = storageClient.delete_file("group1", StringUtils.substringAfter(filePath, "group1/"));
            log.info(String.valueOf(i));
            if (i != 0) {
                log.info("删除失败");
                return false;
            }
        } catch (Exception e) {
            log.error("删除文件异常");
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 获得可用的storage IP
     *
     * @param trackerClient
     * @param trackerServer
     * @return 返回storage IP
     */
    private static String getStorageServerIp(TrackerClient trackerClient, TrackerServer trackerServer) {
        String storageIp = null;
        if (trackerClient != null && trackerServer != null) {
            try {
                StorageServer storageServer = trackerClient.getStoreStorage(trackerServer, "group1");
                storageIp = storageServer.getInetSocketAddress().getAddress().getHostAddress();
            } catch (IOException | MyException e) {
                e.printStackTrace();
            }
        }
        return storageIp;
    }

    /**
     * 得到Storage服务
     *
     * @param storageIp
     * @return 返回Storage服务
     */
    private static StorageServer getStorageServer(String storageIp) {
        StorageServer storageServer = null;
        if (storageIp != null && !("").equals(storageIp)) {
            try {
                // ip port store_path下标
                storageServer = new StorageServer(storageIp, 23000, 0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return storageServer;
    }





    /**
     * 文件大小限制
     *
     * @param len
     * @param size
     * @param unit
     * @return
     */
    private static boolean checkFileSize(Long len, int size, String unit) {
        double fileSize = 0;
        if ("B".equals(unit.toUpperCase())) {
            fileSize = (double) len;
        } else if ("K".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1024;
        } else if ("M".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1048576;
        } else if ("G".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1073741824;
        }
        if (fileSize > size) {
            return false;
        }
        return true;
    }

}
